package com.example.proxy.dynamic_proxy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * <P> @Author: SongKeCheng
 * <P> Type: Class
 * <P> Description: JDK 的动态代理
 * <P> Date: 2024/7/22:14:29
 */

@SuppressWarnings({"unchecked", ""})
public class ServiceProxyFactory {
    private static final Logger log = LoggerFactory.getLogger(ServiceProxyFactory.class);

    //getProxyTransaction
    public static <T> T getProxyTransaction(T obj) {
        Class<?> clazz = obj.getClass();
        ClassLoader classLoader = clazz.getClassLoader();
        Class<?>[] interfaces = clazz.getInterfaces();
        InvocationHandler invocationHandler = new InvocationHandler() {

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                log.info("开启事务");
                //obj 是 被代理对象
                //args 是参数
                Object result = method.invoke(obj, args);
                log.info("提交事务");
                return result;
            }
        };
        Object proxy = Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);

        return (T) proxy;
    }

    /**
     * 提供工厂方法：用来创建并返回代理类对象
     * 记录方法的执行完成时间
     */
    public static <T> T getProxyCalCallTime(T obj) {
        Class<?> clazz = obj.getClass();
        ClassLoader classLoader = clazz.getClassLoader();
        Class<?>[] interfaces = clazz.getInterfaces();
        InvocationHandler invocationHandler = new InvocationHandler() {

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                long start = System.currentTimeMillis();
                //obj 是 被代理对象
                //args 是参数
                Object result = method.invoke(obj, args);
                long end = System.currentTimeMillis();
                log.info("当前方法调用总时长:{}", end - start);
                return result;
            }
        };
        Object proxy = Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);

        return (T) proxy;
    }
}
